package com.mezz.bones.mgb;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * WMS扩展代码生成器 - 方案二：使用FastAutoGenerator + CustomFile.Builder
 * 支持生成完整的分层架构代码：Entity、Request、Response、Mapper、Repository、Service、Client、Controller
 */
public class MallExtendedGenerator {

    // 数据库配置
    private static final String DB_URL = "jdbc:mysql://117.72.117.89:13306/mall?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true";
    private static final String DB_USERNAME = "root";
    private static final String DB_PASSWORD = "3sI7otA4P9B4o";
    
    // 基础配置
    private static final String AUTHOR = "mezz";
    private static final String BASE_PACKAGE = "com.rh.";
    
    // 模块配置
    private static final String MODULE_NAME = "product"; // 业务模块名
    
    // 添加输出目录配置
    private static final String OUTPUT_DIR = "c:\\generated-code\\rh"; // 生成文件的输出目录
    
    public static void main(String[] args) {
        // 要生成的表名
        String[] tableNames = {"resource_feedback"};
        
        generateCode(tableNames);
    }
    
    public static void generateCode(String[] tableNames) {
        FastAutoGenerator.create(DB_URL, DB_USERNAME, DB_PASSWORD)
                // 全局配置
                .globalConfig(builder -> {
                    builder.author(AUTHOR) // 设置作者
                            .enableSwagger() // 开启 swagger 模式
                            .outputDir(OUTPUT_DIR) // 指定输出目录
                            .dateType(DateType.ONLY_DATE) // 时间策略
                            .commentDate("yyyy-MM-dd");
                })
                .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
                    String fieldType = metaInfo.getTypeName().toLowerCase();
                    // 将 tinyint 映射为 Integer
                    if (fieldType.contains("tinyint")) {
                        return DbColumnType.BOOLEAN;
                    }
                    return typeRegistry.getColumnType(metaInfo);
                }))
                // 包配置
                .packageConfig(builder -> {
                    builder.parent(BASE_PACKAGE + MODULE_NAME) // 设置父包名
                            .entity("domain.entity") // 设置实体类包名
                            .mapper("mapper"); // 设置 Mapper 接口包名
                })
                // 策略配置
                .strategyConfig(builder -> {
                    builder.addInclude(tableNames) // 设置需要生成的表名
                            // Entity 策略配置
                            .entityBuilder()
                            .enableTableFieldAnnotation()
                            .enableLombok() // 开启 lombok 模式
                            .enableRemoveIsPrefix() // 开启 Boolean 类型字段移除 is 前缀
                            .naming(NamingStrategy.underline_to_camel) // 数据库表映射到实体的命名策略
                            .idType(IdType.ASSIGN_ID) // 全局主键类型
                            .formatFileName("%s") // 格式化文件名称
                            .enableFileOverride()

                            // Mapper 策略配置
                            .mapperBuilder()
                            .enableFileOverride()
                            .enableMapperAnnotation() // 开启 @Mapper 注解
                            .formatMapperFileName("I%sMapper") // 格式化 mapper 文件名称
                            .formatXmlFileName("%sMapper") // 格式化 xml 实现类文件名称
                            
                            // 禁用默认的 Service 和 Controller 生成
                            .serviceBuilder()
                            .disable()
                            
                            .controllerBuilder()
                            .disable();
                })
                // 模板引擎配置
                .templateEngine(new FreemarkerTemplateEngine())
                // 注入配置
                .injectionConfig(consumer -> {
                    // 自定义配置 Map
                    Map<String, Object> customMap = getCustomConfig();
                    consumer.customMap(customMap);
                    
                    // 使用 CustomFile.Builder 配置自定义文件
                    List<CustomFile> customFiles = getCustomFiles();
                    
                    consumer.customFile(customFiles);
                })
                .execute();
    }

    public static List<CustomFile> getCustomFiles() {
        List<CustomFile> customFiles = new ArrayList<>();

        // Request 类
        customFiles.add(new CustomFile.Builder()
                .fileName("BatchDeleteRequest.java")
                .templatePath("/templates/batchDeleteRequest.java.ftl")
                .packageName("domain.request")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("CreateRequest.java")
                .templatePath("/templates/createRequest.java.ftl")
                .packageName("domain.request")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("DeleteRequest.java")
                .templatePath("/templates/deleteRequest.java.ftl")
                .packageName("domain.request")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("UpdateRequest.java")
                .templatePath("/templates/updateRequest.java.ftl")
                .packageName("domain.request")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("PageRequest.java")
                .templatePath("/templates/pageRequest.java.ftl")
                .packageName("domain.request")
                .enableFileOverride()
                .build());

        // Response
        customFiles.add(new CustomFile.Builder()
                .fileName("DetailResponse.java")
                .templatePath("/templates/detailResponse.java.ftl")
                .packageName("domain.response")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("PageResponse.java")
                .templatePath("/templates/pageResponse.java.ftl")
                .packageName("domain.response")
                .enableFileOverride()
                .build());

        // Repository 接口类 - 正确的I前缀配置
        customFiles.add(new CustomFile.Builder()
                .fileName(".java")
                .formatNameFunction(tableInfo -> "I" + tableInfo.getEntityName() + "Repository")
                .templatePath("/templates/repository.java.ftl")
                .packageName("repository")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("RepositoryImpl.java")
                .templatePath("/templates/repositoryImpl.java.ftl")
                .packageName("repository.impl")
                .enableFileOverride()
                .build());

        // Service 接口类 - 已经有I前缀，但文件名需要调整
        customFiles.add(new CustomFile.Builder()
                .fileName(".java")
                .formatNameFunction(tableInfo -> "I" + tableInfo.getEntityName() + "Service")
                .templatePath("/templates/service.base.java.ftl")
                .packageName("service")
                .enableFileOverride()
                .build());

        customFiles.add(new CustomFile.Builder()
                .fileName("ServiceImpl.java")
                .templatePath("/templates/serviceImpl.base.java.ftl")
                .packageName("service.impl")
                .enableFileOverride()
                .build());

        // Client 接口类 - 添加I前缀
        customFiles.add(new CustomFile.Builder()
                .fileName(".java")
                .formatNameFunction(tableInfo -> "I" + tableInfo.getEntityName() + "Client")
                .templatePath("/templates/client.java.ftl")
                .packageName("provider.client")
                .enableFileOverride()
                .build());
                
        customFiles.add(new CustomFile.Builder()
                .fileName("ClientImpl.java")
                .templatePath("/templates/clientImpl.java.ftl")
                .packageName("provider.client.impl")
                .enableFileOverride()
                .build());
    
        // Controller 类
        customFiles.add(new CustomFile.Builder()
                .fileName("Controller.java")
                .templatePath("/templates/controller.java.ftl")
                .packageName("controller")
                .enableFileOverride()
                .build());

        return customFiles;
    }
    
    /**
     * 获取自定义配置
     */
    private static Map<String, Object> getCustomConfig() {
        Map<String, Object> customMap = new HashMap<>();
        
        // 模块名
        customMap.put("moduleName", MODULE_NAME);
        customMap.put("module", MODULE_NAME);
        
        // 添加输出目录配置
        customMap.put("outputDir", OUTPUT_DIR);
        
        // 包路径配置
        customMap.put("requestPackage", BASE_PACKAGE + MODULE_NAME + ".domain.request");
        customMap.put("responsePackage", BASE_PACKAGE + MODULE_NAME + ".domain.response");
        customMap.put("repositoryPackage", BASE_PACKAGE + MODULE_NAME + ".repository");
        customMap.put("repositoryImplPackage", BASE_PACKAGE + MODULE_NAME + ".repository.impl");
        customMap.put("servicePackage", BASE_PACKAGE + MODULE_NAME + ".service");
        customMap.put("serviceImplPackage", BASE_PACKAGE + MODULE_NAME + ".service.impl");
        customMap.put("clientPackage", BASE_PACKAGE + MODULE_NAME + ".client");
        customMap.put("clientImplPackage", BASE_PACKAGE + MODULE_NAME + ".client.impl");
        customMap.put("controllerPackage", BASE_PACKAGE + MODULE_NAME + ".controller");
        customMap.put("enumPackage", BASE_PACKAGE + MODULE_NAME + ".domain.enums");
        
        return customMap;
    }
} // 主类结束大括号